﻿using System;
using System.Collections.Generic;
using System.Text;

namespace TCCHWLib
{
    public class CommunicationBus
    {
        private List<IBusComponent> m_Components = null;
        private Memory m_SharedMemory = null;

        public Memory SharedMemory
        {
            get { return m_SharedMemory; }
            set { m_SharedMemory = value; }
        }
        public List<IBusComponent> Components
        {
            get { return m_Components; }
            set { m_Components = value; }
        }

        public CommunicationBus()
        {
            m_Components = new List<IBusComponent>();
        }

        #region ISubject code (Observer Pattern)
        public void Attach(IBusComponent component)
        {
            if (!m_Components.Contains(component))
                m_Components.Add(component);
        }
        public void Dettach(IBusComponent component)
        {
            if (m_Components.Contains(component))
                m_Components.Remove(component);
        }
        #endregion


        #region IObject code (Notification Code)
        private void NotifyRead(int address)
        {
            foreach (IBusComponent component in m_Components)
                component.NotifyRead(address);
        }
        private MESI IsRead(int address)
        {
            MESI MesiTag = MESI.Exclusive;
            foreach (IBusComponent component in m_Components)
            {
                if (component.IsRead(address))
                    MesiTag = MESI.Shared;
            }
            return MesiTag;
        }
        public bool CheckWriteSignature(int address)
        {
            bool WriteSignature = false;
            foreach (IBusComponent component in m_Components)
            {
                if (component.CheckWriteSignature(address))
                    WriteSignature = true;
            }
            return WriteSignature;
        }
        public bool CheckReadSignature(int address)
        {
            bool ReadSignature = false;
            foreach (IBusComponent component in m_Components)
            {
                if (component.CheckReadSignature(address))
                {
                    ReadSignature = true;
                }
            }
            return ReadSignature;
        }
        #endregion

        #region Bus Behavior
        public int Allocate(int size)
        {
            return SharedMemory.Allocate(size);
        }
        public void Deallocate(int address,int size)
        {
            SharedMemory.Deallocate(address,size);
        }
        public object Read(int address, out MESI mesiTag)
        {
            mesiTag = MESI.Exclusive;
            NotifyRead(address);
            mesiTag = IsRead(address);
            return SharedMemory.Read(address);
        }
        public bool Write(int address,object value)
        {
            CheckReadSignature(address);
            return SharedMemory.Write(address, value);
        }
        #endregion
    }
}
